﻿using System;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using System.Threading;
using DataCenter.Share;
using Microsoft.SqlServer.Server;
using System.Collections.Generic;
using System.Diagnostics;

namespace DataCenter.Clr
{
    public class CenterEntry
    {
        public const int SUCCESS = 1;
        public const int RETURN = 0;
        public const int ERROR = -1;
        public const int LOCKED = -2;
        public static readonly Version VERSION = new Version(1, 11, 111, 2);

        public const int LOCK_TIMEOUT = 600000;       // 超时10分钟

        static CenterEntry()
        {
            _Lock = new ReaderWriterLock();
        }
        private static ReaderWriterLock _Lock;

        public CenterEntry()
        {
            this._CenterSetting = CenterSetting.CreateInstance();
            this._TableSetting = TableSetting.CreateInstance();
            this._RecentManager = RecentValueManager.GetInstance();
        }
        public CenterEntry(int maxFieldCount)
            : this()
        {
            this._MaxFieldCount = maxFieldCount;
        }
        private int _MaxFieldCount;
        private CenterSetting _CenterSetting;
        private TableSetting _TableSetting;
        private RecentValueManager _RecentManager;

        public int Aggregate(string objectId, string valueType, string operType, DateTime startTime, DateTime endTime, int step, string groupStyle, string aggregateStyle, string parameters)
        {
            try
            {
                _Lock.AcquireReaderLock(LOCK_TIMEOUT);
                try
                {
                    int startIndex = 0, endIndex = 0;
                    if (!_TableSetting.AdjustTimeRegion(startTime, endTime, ref startIndex, ref endIndex))
                        return RETURN;

                    Aggregation aggregation = Aggregation.CreateInstance(groupStyle, aggregateStyle, parameters);
                    if (aggregation == null) return ERROR;
                    aggregation.Build(aggregateStyle);

                    int[] operTypes = Utils.ConvertStringToArray(operType);
                    using (SqlConnection connection = new SqlConnection("context connection = true"))
                    {
                        connection.Open();
                        using (SqlCommand command = connection.CreateCommand())
                        {
                            string commandTemplet = "SELECT ObjectId, ValueTime, ValueType, ImportTime, InterpolateTime, BinaryValue FROM {0} WHERE 1 = 1" +
                                GetWhereClause(objectId, valueType, startTime, endTime);

                            StringBuilder cmdStrBuilder = new StringBuilder();
                            for (int i = startIndex; i <= endIndex; i++)
                            {
                                string tableName = _TableSetting.GetTableName(i);
                                cmdStrBuilder.Append(" UNION ALL ");
                                cmdStrBuilder.AppendFormat(commandTemplet, tableName);

                                if (cmdStrBuilder.Length >= 7500 || i == endIndex)
                                {
                                    command.CommandText = cmdStrBuilder.ToString().Substring(11);
                                    command.CommandType = CommandType.Text;
                                    using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
                                    {
                                        while (reader.Read())
                                        {
                                            BinaryRecord record = new BinaryRecord();
                                            record.Build(reader);
                                            record.Build(reader, startTime, endTime, 5, false);
                                            aggregation.AddRecord(record, step, operTypes);
                                        }
                                    }
                                    cmdStrBuilder = new StringBuilder();
                                }
                            }
                        }
                    }

                    if (SqlContext.IsAvailable && !SqlContext.Pipe.IsSendingResults)
                    {
                        SqlDataRecord dataRecord = aggregation.CreateDataRecord();
                        SqlContext.Pipe.SendResultsStart(dataRecord);
                        aggregation.FillDataRecord(dataRecord);            
                        SqlContext.Pipe.SendResultsEnd();
                    }

                    return SUCCESS;
                }
                catch (Exception ex)
                {
                    if (SqlContext.Pipe.IsSendingResults)
                        SqlContext.Pipe.SendResultsEnd();
                    SqlContext.Pipe.Send(ex.Message);
                    SqlContext.Pipe.Send(ex.StackTrace);
                    return ERROR;
                }
                finally
                {
                    _Lock.ReleaseReaderLock();
                }
            }
            catch (ApplicationException)
            {
                return LOCKED;
            }
        }
        public int Insert(int objectId, int valueType, int operType, DateTime valueTime, float value)
        {
            try
            {
                _Lock.AcquireWriterLock(LOCK_TIMEOUT);
                try
                {
                    bool isRecordExist = false;
                    using (SqlConnection connection = new SqlConnection("context connection = true"))
                    {
                        connection.Open();
                        using (SqlCommand command = connection.CreateCommand())
                        {
                            BinaryRecord record = null;

                            string tableName = _TableSetting.GetTableName(valueTime);
                            if (_TableSetting.IsTableExist(valueTime))
                            {
                                string commandString = "SELECT ObjectId, ValueTime, ValueType, ImportTime, InterpolateTime, BinaryValue FROM {0} WHERE 1 = 1" +
                                    GetWhereClause(objectId, valueType, valueTime);
                                commandString = string.Format(commandString, tableName);
                                command.CommandText = commandString;
                                command.CommandType = CommandType.Text;
                                using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
                                {
                                    if (reader.Read())
                                    {
                                        record = new BinaryRecord();
                                        record.Build(reader);

                                        if (valueTime > record.ImportTime)
                                            record.ImportTime = valueTime;
                                        if (record.InterpolateTime > Utils.EMPTY_TIME)
                                        {
                                            record.Build(reader, valueTime.Date, valueTime, 5, false);
                                            DateTime lastTime = record.BinaryValue.GetLastTime(Utils.REAL_FLAG);
                                            if (lastTime < record.InterpolateTime)
                                                record.InterpolateTime = lastTime;
                                        }
                                        else
                                        {
                                            record.Build(reader, valueTime, valueTime, 5, false);
                                        }
                                        isRecordExist = true;
                                    }
                                }
                            }

                            if (record == null)
                            {
                                record = new BinaryRecord();
                                record.ObjectId = objectId;
                                record.ValueType = valueType;
                                record.ValueTime = valueTime.Date;
                                record.BinaryValue = new DayBinary(1, 1);
                                record.ImportTime = valueTime;
                            }

                            Binary binary = record.BinaryValue;
                            binary.SetValue(valueTime, operType, 0, value);

                            if (isRecordExist)
                            {
                                record.UpdateRecord(command, valueTime, valueTime);
                                record.UpdateRecordCount(command);
                            }
                            else
                            {
                                record.CreateRecord(command);
                            }

                            if (operType == Utils.REAL_FLAG)
                                _RecentManager.UpdateRecentValue(command, objectId, valueType, valueTime, value);
                        }
                    }

                    return SUCCESS;
                }
                catch (Exception ex)
                {
                    SqlContext.Pipe.Send(ex.Message);
                    SqlContext.Pipe.Send(ex.StackTrace);
                    return ERROR;
                }
                finally
                {
                    _Lock.ReleaseWriterLock();
                }
            }
            catch (ApplicationException)
            {
                return LOCKED;
            }
        }        
        public int Delete(string objectId, string valueType, DateTime startTime, DateTime endTime)
        {
            try
            {
                _Lock.AcquireWriterLock(LOCK_TIMEOUT);
                try
                {
                    SqlConnectionStringBuilder cnStrbuilder = new SqlConnectionStringBuilder();
                    cnStrbuilder.DataSource = "localhost";
                    cnStrbuilder.InitialCatalog = _CenterSetting.DbName;
                    cnStrbuilder.IntegratedSecurity = true;
                    cnStrbuilder.MultipleActiveResultSets = true;
                    using (SqlConnection connection = new SqlConnection(cnStrbuilder.ConnectionString))
                    {
                        connection.Open();
                        using (SqlCommand command = connection.CreateCommand())
                        {
                            if (startTime.Date == endTime.Date)
                            {
                                if (_TableSetting.IsTableExist(startTime))
                                {
                                    // 开始时间和结束时间为同一天，则直接删除数据
                                    DeleteSingle(connection, command, objectId, valueType, startTime, endTime);
                                }
                            }
                            else
                            {
                                if (startTime != startTime.Date)
                                {
                                    if (_TableSetting.IsTableExist(startTime))
                                    {
                                        // 开始时间不是从0点开始，需要删除从StartTime到23:59
                                        DeleteSingle(connection, command, objectId, valueType, startTime, Utils.GetLastTime(startTime));
                                        startTime = startTime.AddDays(1).Date;
                                    }
                                }
                                if (endTime != endTime.Date)
                                {
                                    if (_TableSetting.IsTableExist(endTime))
                                    {
                                        // 结束时间不是完整一天，需要删除从当天0点到EndTime
                                        DeleteSingle(connection, command, objectId, valueType, endTime.Date, endTime);
                                        endTime = endTime.AddDays(-1).Date;
                                    }
                                }

                                if (startTime <= endTime)
                                {
                                    int startIndex = 0, endIndex = 0;
                                    if (!_TableSetting.AdjustTimeRegion(startTime, endTime, ref startIndex, ref endIndex))
                                        return RETURN;

                                    for (int i = startIndex; i <= endIndex; i++)
                                    {
                                        string tableName = _TableSetting.GetTableName(startTime);
                                        string commandString = "DELETE FROM {0} WHERE 1 = 1" + GetWhereClause(objectId, valueType, startTime, endTime);
                                        command.CommandText = string.Format(commandString, tableName);
                                        command.CommandType = CommandType.Text;
                                        command.ExecuteNonQuery();
                                    }
                                }
                            }
                        }
                    }

                    return SUCCESS;
                }
                catch (Exception ex)
                {
                    SqlContext.Pipe.Send(ex.Message);
                    SqlContext.Pipe.Send(ex.StackTrace);
                    return ERROR;
                }
                finally
                {
                    _Lock.ReleaseWriterLock();
                }
            }
            catch (ApplicationException)
            {
                return LOCKED;
            }
        }
        private int DeleteSingle(SqlConnection connection, SqlCommand command, string objectId, string valueType, DateTime startTime, DateTime endTime)
        {
            try
            {
                string tableName = _TableSetting.GetTableName(startTime);
                string whereClause = GetWhereClause(objectId, valueType, startTime, endTime);
                string commandTemplet = "SELECT ObjectId, ValueTime, ValueType, ImportTime, InterpolateTime, BinaryValue FROM {0} WHERE 1 = 1" + whereClause;                    
                command.CommandText = string.Format(commandTemplet, tableName);
                command.CommandType = CommandType.Text;
                using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
                {
                    while (reader.Read())
                    {
                        BinaryRecord record = new BinaryRecord();
                        record.Build(reader);
                        record.Build(reader, false);

                        using (SqlCommand updateCommand = connection.CreateCommand())
                        {
                            Binary binaryValue = record.BinaryValue;
                            binaryValue.ClearFlag(startTime, endTime);
                            if (binaryValue.RecordCount <= 0)
                            {
                                string commandString = "DELETE FROM {0} WHERE 1 = 1" + whereClause;
                                updateCommand.CommandText = string.Format(commandString, tableName);
                                updateCommand.CommandType = CommandType.Text;
                                updateCommand.ExecuteNonQuery();
                            }
                            else
                            {
                                if (endTime >= record.ImportTime)
                                {
                                    DateTime lastTime = binaryValue.GetLastTime(Utils.REAL_FLAG);
                                    record.ImportTime = lastTime;
                                }
                                if (record.InterpolateTime > Utils.EMPTY_TIME)
                                {
                                    DateTime lastTime = binaryValue.GetLastTime(Utils.REAL_FLAG, startTime.Date, startTime);
                                    record.InterpolateTime = lastTime;
                                }
                                record.UpdateRecord(updateCommand);
                            }
                        }
                    }
                }

                return SUCCESS;
            }
            catch (Exception ex)
            {
                SqlContext.Pipe.Send(ex.Message);
                SqlContext.Pipe.Send(ex.StackTrace);
                return ERROR;
            }
        }        
        public int Query(string objectId, string valueType, string operType, DateTime startTime, DateTime endTime, int step)
        {
            try
            {
                _Lock.AcquireReaderLock(LOCK_TIMEOUT);
                try
                {
                    int startIndex = 0, endIndex = 0;
                    if (!_TableSetting.AdjustTimeRegion(startTime, endTime, ref startIndex, ref endIndex))
                        return RETURN;

                    int[] operTypes = Utils.ConvertStringToArray(operType);
                    using (SqlConnection connection = new SqlConnection("context connection = true"))
                    {
                        connection.Open();
                        using (SqlCommand command = connection.CreateCommand())
                        {
                            string commandTemplet = "SELECT ObjectId, ValueTime, ValueType, ImportTime, InterpolateTime, BinaryValue FROM {0} WHERE 1 = 1" +
                                GetWhereClause(objectId, valueType, startTime, endTime);

                            if (SqlContext.IsAvailable && !SqlContext.Pipe.IsSendingResults)
                            {
                                SqlDataRecord dataRecord = null;
                                dataRecord = CreateRecord(_MaxFieldCount);
                                SqlContext.Pipe.SendResultsStart(dataRecord);

                                StringBuilder cmdStrBuilder = new StringBuilder();
                                for (int i = startIndex; i <= endIndex; i++)
                                {
                                    string tableName = _TableSetting.GetTableName(i);
                                    cmdStrBuilder.Append(" UNION ALL ");
                                    cmdStrBuilder.AppendFormat(commandTemplet, tableName);

                                    if (cmdStrBuilder.Length >= 7500 || i == endIndex)
                                    {
                                        command.CommandText = cmdStrBuilder.ToString().Substring(11);
                                        command.CommandType = CommandType.Text;
                                        using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
                                        {
                                            while (reader.Read())
                                            {
                                                BinaryRecord record = new BinaryRecord();
                                                record.Build(reader);
                                                record.Build(reader, startTime, endTime, 5, false);
                                                record.FillDataRecord(dataRecord, step, operTypes);
                                            }
                                        }

                                        cmdStrBuilder = new StringBuilder();
                                    }
                                }
                                SqlContext.Pipe.SendResultsEnd();
                            }
                        }
                    }

                    return SUCCESS;
                }
                catch (Exception ex)
                {
                    if (SqlContext.Pipe.IsSendingResults)
                        SqlContext.Pipe.SendResultsEnd();
                    SqlContext.Pipe.Send(ex.Message);
                    SqlContext.Pipe.Send(ex.StackTrace);
                    return ERROR;
                }
                finally
                {
                    _Lock.ReleaseReaderLock();
                }
            }
            catch (ApplicationException)
            {
                return LOCKED;
            }
        }
        public int QueryInfo(string objectId, string objectType)
        {
            try
            {
                using (SqlConnection connection = new SqlConnection("context connection = true"))
                {
                    connection.Open();
                    using (SqlCommand command = connection.CreateCommand())
                    {
                        if (SqlContext.IsAvailable && !SqlContext.Pipe.IsSendingResults)
                        {
                            string commandString = "SELECT * FROM Object WHERE 1 = 1";
                            if (!string.IsNullOrEmpty(objectId)) commandString += " AND ObjectId IN (" + objectId + ")";
                            if (!string.IsNullOrEmpty(objectType)) commandString += " AND ObjectType IN (" + objectType + ")";

                            command.CommandText = commandString;
                            command.CommandType = CommandType.Text;
                            SqlContext.Pipe.ExecuteAndSend(command);
                        }
                    }
                }

                return SUCCESS;
            }
            catch (Exception ex)
            {
                if (SqlContext.Pipe.IsSendingResults)
                    SqlContext.Pipe.SendResultsEnd();
                SqlContext.Pipe.Send(ex.Message);
                SqlContext.Pipe.Send(ex.StackTrace);
                return ERROR;
            }
        }
        public int QueryRecentValue(string objectId, string valueType)
        {
            try
            {
                using (SqlConnection connection = new SqlConnection("context connection = true"))
                {
                    connection.Open();
                    using (SqlCommand command = connection.CreateCommand())
                    {
                        string commandString = "SELECT ObjectId, ValueType, ValueTime, R__0 FROM RecentValueTable WHERE 1 = 1" +
                            GetWhereClause(objectId, valueType);

                        command.CommandText = commandString;
                        command.CommandType = CommandType.Text;
                        SqlContext.Pipe.ExecuteAndSend(command);
                    }
                }
                return SUCCESS;
            }
            catch (Exception ex)
            {
                SqlContext.Pipe.Send(ex.Message);
                SqlContext.Pipe.Send(ex.StackTrace);
                return ERROR;
            }
        }
        public int QueryLastValue(string objectId, string valueType)
        {
            try
            {
                _Lock.AcquireReaderLock(LOCK_TIMEOUT);
                try
                {
                    using (SqlConnection connection = new SqlConnection("context connection = true"))
                    {
                        connection.Open();
                        using (SqlCommand command = connection.CreateCommand())
                        {
                            if (SqlContext.IsAvailable && !SqlContext.Pipe.IsSendingResults)
                            {
                                SqlDataRecord dataRecord = null;
                                dataRecord = CreateRecord(_MaxFieldCount);

                                SqlContext.Pipe.SendResultsStart(dataRecord);

                                int[] idArray = Algorithm.ParseTupleString(objectId);
                                int[] typeArray = Algorithm.ParseTupleString(valueType);
                                foreach (int type in typeArray)
                                {
                                    List<int> idList = new List<int>(idArray);

                                    for (int i = _TableSetting.EndTableIndex; i >= _TableSetting.StartTableIndex; i--)
                                    {
                                        string objectIds = Utils.ArrayToString(idList.ToArray());
                                        string tableName = _TableSetting.GetTableName(i);
                                        string commandString = "SELECT ObjectId, ValueTime, ValueType, ImportTime, InterpolateTime, BinaryValue FROM {0} WHERE 1 = 1" +
                                            GetWhereClause(objectIds, type.ToString()) + " ORDER BY ObjectId, ValueTime DESC";

                                        command.CommandText = string.Format(commandString, tableName);
                                        command.CommandType = CommandType.Text;
                                        using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
                                        {
                                            while (reader.Read())
                                            {
                                                BinaryRecord record = new BinaryRecord();
                                                record.Build(reader);
                                                record.Build(reader, false);

                                                int idIndex = idList.BinarySearch(record.ObjectId);
                                                if (idIndex >= 0)
                                                {
                                                    Binary binaryValue = record.BinaryValue;
                                                    TimePoint lastPoint = binaryValue.GetLastPoint(Utils.REAL_FLAG);
                                                    if (lastPoint != null)
                                                    {
                                                        dataRecord.SetInt32(0, record.ObjectId);
                                                        dataRecord.SetInt32(1, record.ValueType);
                                                        dataRecord.SetDateTime(2, lastPoint.Time);
                                                        dataRecord.SetInt32(3, lastPoint.Flag);
                                                        dataRecord.SetFloat(4, lastPoint.Value0);
                                                        SqlContext.Pipe.SendResultsRow(dataRecord);

                                                        idList.RemoveAt(idIndex);
                                                        if (idList.Count == 0)
                                                            break;
                                                    }
                                                }
                                            }
                                        }
                                        if (idList.Count == 0)
                                            break;
                                    }
                                }
                                SqlContext.Pipe.SendResultsEnd();
                            }
                        }
                    }
                    return SUCCESS;
                }
                catch (Exception ex)
                {
                    SqlContext.Pipe.Send(ex.Message);
                    SqlContext.Pipe.Send(ex.StackTrace);
                    return ERROR;
                }
                finally
                {
                    _Lock.ReleaseReaderLock();
                }
            }
            catch (ApplicationException)
            {
                return LOCKED;
            }
        }
        public IEnumerable Select(string objectId, string valueType, string operType, DateTime startTime, DateTime endTime, int step)
        {
            try
            {
                _Lock.AcquireReaderLock(LOCK_TIMEOUT);
                try
                {
                    int startIndex = 0, endIndex = 0;
                    if (!_TableSetting.AdjustTimeRegion(startTime, endTime, ref startIndex, ref endIndex))
                        return null;

                    int[] operTypes = Utils.ConvertStringToArray(operType);
                    RecordCollection collection = new RecordCollection(step, operTypes);
                    using (SqlConnection connection = new SqlConnection("context connection = true"))
                    {
                        connection.Open();
                        using (SqlCommand command = connection.CreateCommand())
                        {
                            Binary.CreateCache(_CenterSetting.MaxMemoryLimit);

                            string commandTemplet = "SELECT ObjectId, ValueTime, ValueType, ImportTime, InterpolateTime, BinaryValue FROM {0} WHERE 1 = 1" +
                                GetWhereClause(objectId, valueType, startTime, endTime);

                            StringBuilder cmdStrBuilder = new StringBuilder();
                            for (int i = startIndex; i <= endIndex; i++)
                            {
                                string tableName = _TableSetting.GetTableName(i);
                                cmdStrBuilder.Append(" UNION ALL ");
                                cmdStrBuilder.AppendFormat(commandTemplet, tableName);

                                if (cmdStrBuilder.Length >= 7500 || i == endIndex)
                                {
                                    command.CommandText = cmdStrBuilder.ToString().Substring(11);
                                    command.CommandType = CommandType.Text;
                                    using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
                                    {
                                        while (reader.Read())
                                        {
                                            BinaryRecord record = new BinaryRecord();
                                            record.Build(reader);
                                            record.Build(reader, startTime, endTime, 5, true);
                                            collection.Add(record);
                                        }
                                    }
                                    cmdStrBuilder = new StringBuilder();
                                }
                            }
                        }
                    }

                    return collection;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    _Lock.ReleaseReaderLock();
                }
            }
            catch (ApplicationException ex)
            {
                throw ex;
            }
        }
        public IEnumerable SelectInfo(string objectId, string objectType)
        {
            try
            {
                DataTable table = new DataTable();
                using (SqlConnection connection = new SqlConnection("context connection = true"))
                {
                    connection.Open();
                    using (SqlCommand command = connection.CreateCommand())
                    {
                        string commandString = "SELECT ObjectId, ObjectType, ObjectName FROM Object WHERE 1 = 1";
                        if (!string.IsNullOrEmpty(objectId)) commandString += " AND ObjectId IN (" + objectId + ")";
                        if (!string.IsNullOrEmpty(objectType)) commandString += " AND ObjectType IN (" + objectType + ")";
    
                        command.CommandText = commandString;
                        command.CommandType = CommandType.Text;                        
                        using (SqlDataAdapter adapter = new SqlDataAdapter(command))
                        {
                            adapter.Fill(table);
                        }
                    }
                }
                return table.Rows;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public IEnumerable SelectRecentValue(string objectId, string objectType)
        {
            try
            {
                DataTable table = new DataTable();
                using (SqlConnection connection = new SqlConnection("context connection = true"))
                {
                    connection.Open();
                    using (SqlCommand command = connection.CreateCommand())
                    {
                        string commandString = "SELECT ObjectId, ValueType, ValueTime, R__0 FROM RecentValueTable WHERE 1 = 1" +
                            GetWhereClause(objectId, objectType);

                        command.CommandText = commandString;
                        command.CommandType = CommandType.Text;
                        using (SqlDataAdapter adapter = new SqlDataAdapter(command))
                        {
                            adapter.Fill(table);
                        }
                    }
                }
                return table.Rows;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public int CallApp(ExecTypes execType, string objectId, DateTime startTime, DateTime endTime)
        {
            try
            {
                _Lock.AcquireWriterLock(LOCK_TIMEOUT);
                try
                {
                    string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, _CenterSetting.AppFilePath);
                    string args = "DB \"" + _CenterSetting.DbName + "\" ";
                    args += "ID \"" + objectId + "\" ";
                    args += "TIME0 \"" + startTime + "\" ";
                    args += "TIME1 \"" + endTime + "\" ";
                    args += "OPER \"" + (int)execType + "\" ";

                    int result = Utils.CallApp(filePath, args);
                    _TableSetting.Initialize();
                    return result;
                }
                catch (Exception ex)
                {
                    SqlContext.Pipe.Send(ex.Message);
                    SqlContext.Pipe.Send(ex.StackTrace);
                    return ERROR;
                }
                finally
                {
                    _Lock.ReleaseWriterLock();
                }
            }
            catch (ApplicationException)
            {
                return LOCKED;
            }
        }
        public static int RefreshSetting()
        {
            if (_Lock.IsReaderLockHeld || _Lock.IsWriterLockHeld)
                return LOCKED;

            try
            {
                using (SqlConnection connection = new SqlConnection("context connection = true"))
                {
                    connection.Open();
                    using (SqlCommand command = connection.CreateCommand())
                    {
                        CenterSetting centerSetting = CenterSetting.GetInstance();
                        centerSetting.Initialize(command);
                        SqlContext.Pipe.Send("CenterSetting");
                        SqlContext.Pipe.Send("\tDBName = " + centerSetting.DbName);
                        SqlContext.Pipe.Send("\tAppPath = " + centerSetting.AppFilePath);
                        SqlContext.Pipe.Send("\tLogPath = " + centerSetting.LogFilePath);
                        SqlContext.Pipe.Send("\tMemoryLimite = " + centerSetting.MaxMemoryLimit);

                        TableSetting tableSetting = TableSetting.GetInstance();
                        tableSetting.Initialize(command);
                        SqlContext.Pipe.Send("TableSetting");
                        SqlContext.Pipe.Send("\tMonthStep = " + tableSetting.SplitMonthStep);
                        SqlContext.Pipe.Send("\tTableName = " + tableSetting.TableName);
                        SqlContext.Pipe.Send("\tStartIndex = " + tableSetting.StartTableIndex);
                        SqlContext.Pipe.Send("\tEndIndex = " + tableSetting.EndTableIndex);
                    }
                }

                return SUCCESS;
            }
            catch (Exception ex)
            {
                SqlContext.Pipe.Send(ex.Message);
                SqlContext.Pipe.Send(ex.StackTrace);
                return ERROR;
            }

        }

        private string GetWhereClause(int objectId, int valueType, DateTime valueTime)
        {
            string whereClause = GetWhereClause(objectId, valueType);
            whereClause += GetWhereClause(valueTime);
            return whereClause;
        }
        private string GetWhereClause(string objectId, string valueType, DateTime startTime, DateTime endTime)
        {
            string whereClause = GetWhereClause(objectId, valueType);
            whereClause += GetWhereClause(startTime, endTime);
            return whereClause;
        }
        private string GetWhereClause(int objectId, int valueType)
        {
            string whereClause = " AND ObjectId = " + objectId;
            whereClause += " AND ValueType = " + valueType;
            return whereClause;
        }
        private string GetWhereClause(string objectId, string valueType)
        {
            string whereClause = "";
            if (!string.IsNullOrEmpty(objectId)) whereClause += " AND ObjectId IN (" + objectId + ")";
            if (!string.IsNullOrEmpty(valueType)) whereClause += " AND ValueType IN (" + valueType + ")";
            return whereClause;
        }
        private string GetWhereClause(DateTime valueTime)
        {            
            return " AND ValueTime = '" + valueTime.Date + "'";
        }
        private string GetWhereClause(DateTime startTime, DateTime endTime)
        {
            if (startTime == endTime)
                return GetWhereClause(startTime);

            string whereClause = " AND ValueTime >= '" + startTime.Date + "'";
            whereClause += " AND ValueTime <= '" + endTime.Date + "'";
            return whereClause;
        }
        private SqlDataRecord CreateRecord(int fieldCount)
        {
            SqlMetaData[] metaDatas = new SqlMetaData[fieldCount + 4];
            metaDatas[0] = new SqlMetaData("ObjectId", SqlDbType.Int);
            metaDatas[1] = new SqlMetaData("ValueType", SqlDbType.Int);
            metaDatas[2] = new SqlMetaData("ValueTime", SqlDbType.DateTime);
            metaDatas[3] = new SqlMetaData("OperType", SqlDbType.Int);
            for (int i = 0; i < fieldCount; i++)
                metaDatas[i + 4] = new SqlMetaData("R__" + i, SqlDbType.Real);
            SqlDataRecord record = new SqlDataRecord(metaDatas);
            return record;
        }
    }
}
